//登录注册相关功能实现
#include "login.h"
void token_generate(char *token,int len_of_token){//随机生成token
	for (int i = 0; i < len_of_token; i++) {
		srand((unsigned)(i+time(NULL)));
		token[i] = rand() % 26 + 'a';
	}
}
void tail_insert(pnQue_t pnq,Client_State_t* CS) {//尾插法建立用于处理普通命令的链表
	CS->next = NULL;
	if (pnq->que_head == NULL) {
		pnq->que_head = CS;
		pnq->que_tail = CS;
	}else {
		pnq->que_tail->next = CS;
		pnq->que_tail = CS;
	}
}
int verify_passwd(char* username,char* password){//验证成功返回0，失败返回-1； 
    int i; 
    char query[100]={0};
    char result[200]={0};
    char salt[50]={0};
    sprintf(query,"select UserPasswd from UserPassword where UserName = '%s'",username);
    search_from_database(query,result);
    if(strlen(result)==0){
        return -1;
    }
    for(i=0;result[i]!=' ';i++);
    result[i]=0;
    sprintf(query,"select salt from UserPassword where UserName = '%s'",username);
    search_from_database(query,salt);
    for(i=0;salt[i]!=' ';i++);
    salt[i]=0;
    if(strcmp(result,crypt(password,salt))==0){
        return 0;
    }else{
        return -1;
    }
} 
int do_register_or_login_or_token(int new_fd,Factory_t* pf,train_state_t* pt,pnQue_t pnq){//登录或者注册函数
    int code;
    char query[100];
    char result[100];
    int ret;
    char username[100];
    char password[100];
TAG1:
    bzero(username,100);
    bzero(password,100);
    bzero(query,100);
    bzero(result,100);
    ret=recv_session(new_fd,pt);
    SELFFUNC_ERR_CHECK(ret,"recv_session")
    if(pt->state==REGISTER){
        Client_State_t* CS=(Client_State_t*)calloc(1,sizeof(Client_State_t));
        bzero(CS,sizeof(Client_State_t));
        CS->new_fd=new_fd;
        token_generate(CS->token,24);
        strcpy(CS->user_name,pt->buf);
        recv_session(new_fd,pt);
        strcpy(password,pt->buf);
        register_to_database(CS->user_name,password);
        sprintf(query,"select code from FileList where filename = '%s';",CS->user_name);
        search_from_database(query,result);
        code=atoi(result);
        CS->code=code;
        tail_insert(pnq,CS);
        return 1;
    }else if(pt->state==LOGIN){
        strcpy(username,pt->buf);
        recv_session(new_fd,pt);
        strcpy(password,pt->buf);
        int ret=verify_passwd(username,password);
        if(ret==0){
            Client_State_t* CS=(Client_State_t*)calloc(1,sizeof(Client_State_t));
            bzero(CS,sizeof(Client_State_t));
            CS->new_fd=new_fd;
            token_generate(CS->token,24);
            strcpy(CS->user_name,username);
            sprintf(query,"select code from FileList where filename = '%s';",CS->user_name);
            search_from_database(query,result);
            code=atoi(result);
            CS->code=code;
            tail_insert(pnq,CS);
        }else{
            pt->state=LOGINFAIL;
            pt->data_len=4;
            send_n(new_fd,&pt->data_len,4);
            send_n(new_fd,&pt->state,pt->data_len);
            goto TAG1;
        }
        return 1;
    }else if(pt->state==TOKEN){ //token的buf部分放的是token值,根据数据库中的token值验证token正确与否
        char token_temp[25]={0};
        printf("进入tokenle\n");
        strcpy(token_temp,pt->buf);
        pClient_State_t ptemp=pnq->que_head;
        for(;ptemp&&strcmp(ptemp->token,token_temp)!=0;ptemp=ptemp->next);
        if(ptemp==NULL){
            close(new_fd);//如果token没有匹配则关闭缓冲区
        }else{
            recv_session(new_fd,pt);
            printf("仆人来了\n");
            printf("来%d了,%d的是%s\n",pt->state,pt->state,pt->buf);
            pNode_t p=(pNode_t)calloc(1,sizeof(Node_t));//新建一个用于下载上传的节点，并放入队列
            bzero(p,sizeof(Node_t));
            p->new_fd=new_fd;
            p->state=pt->state;//存的上传还是下载
            strcpy(p->filename,pt->buf);//存文件名
            p->code=ptemp->code;
            strcpy(p->user_name,ptemp->user_name);
            pthread_mutex_lock(&((pf->que).mutex));//加锁，放队列，解锁
            que_set(&(pf->que),p);
            pthread_mutex_unlock(&((pf->que).mutex));
            pthread_cond_signal(&pf->cond);//使条件成立
        }
        return 2;
    }
}
